<?php
namespace app\models;
use ac\component\tool\Tool;
use app\models\Basic;

use Yii;

class GoodsCategory extends Basic
{  
    public static function tableName()
    {
        return '{{%pj8_goods_category}}';
    }

    public function rules()
    {
        return [
            ['catid', 'integer'],
            ['name', 'required', 'message' => 'name不能为空', 'on' => 'add'],
            ['name', 'string', 'message' => 'name必须是字符串',
                     'min' => 1, 'tooShort' => 'name最短1位',
                     'max' => 16, 'tooLong' => 'name最长16位'],
            ['icon', 'default', 'value' => ''],
            ['icon', 'string', 'message' => 'icon必须是字符串', 
                     'max' => 256, 'tooLong' => 'icon最长256位'],
            ['parentid', 'required', 'message' => 'parentid不能为空', 'on' => 'add'],
            ['parentid', 'integer', 'message' => 'parentid必须为数字，或数字字符串', 
                         'min'=>0, 'tooSmall' => 'parentid最小存储0', 
                         'max'=>65535, 'tooBig' => 'parentid最大存储65535'],
            ['allparentid', 'default', 'value' => '0'],
            ['allparentid', 'string', 'message' => 'allparentid必须是字符串', 
                              'max' => 512, 'tooLong' => 'allparentid最长512位'],
            ['child', 'default', 'value' => 1],
            ['child', 'integer', 'message' => 'child必须为数字，或数字字符串'],
            ['child', 'in', 'range' => array(1, 2), 'message' => 'child值必须在1,2,3中选择'],
            ['allchildid', 'default', 'value' => ''],
            ['allchildid', 'string', 'message' => 'allchildid必须是字符串', 
                             'max' => 512, 'tooLong' => 'allchildid最长512位'],   
            ['preview', 'default', 'value' => ''],
            ['preview', 'string', 'message' => 'preview必须是字符串'],
            // ['seo_title', 'default', 'value' => ''],
            ['seo_title', 'string', 'message' => 'seo_title必须是字符串', 
                  'max' => 32, 'tooLong' => 'seo_title最长32位'],
            ['seo_keyword', 'string', 'message' => 'seo_keyword必须是字符串', 
                  'max' => 32, 'tooLong' => 'seo_keyword最长32位'],
            // ['seo_describe', 'default', 'value' => ''],
            ['seo_describe', 'string', 'message' => 'a必须是字符串',
                  'min' => 2, 'tooShort' => 'seo_describe最短2位',
                  'max' => 512, 'tooLong' => 'seo_describe最长512位'],
            ['outside', 'default', 'value' => 1],
            ['outside', 'integer', 'message' => 'outside必须为数字，或数字字符串'],
            ['outside', 'in', 'range' => array(1, 2), 'message' => 'outside值必须在1,2中选择'],
            ['url_target', 'default', 'value' => 1],
            ['url_target', 'integer', 'message' => 'url_target必须为数字，或数字字符串'],
            ['url_target', 'in', 'range' => array(1, 2), 'message' => 'url_target值必须在1,2中选择'],
            ['outside_url', 'default', 'value' => ''],
            ['outside_url', 'string', 'message' => 'outside_url必须是字符串', 
                  'max' => 64, 'tooLong' => 'outside_url最长64位'],
            ['flag', 'default', 'value' => 2],
            ['flag', 'integer', 'message' => 'flag必须为数字，或数字字符串'],
            ['flag', 'in', 'range' => array(1, 2), 'message' => 'flag值必须在1,2中选择'],
            ['page_tpl', 'default', 'value' => ''],
            ['page_tpl', 'string', 'message' => 'page_tpl必须是字符串', 
                  'max' => 64, 'tooLong' => 'page_tpl最长64位'],
            ['list_tpl', 'default', 'value' => ''],
            ['list_tpl', 'string', 'message' => 'list_tpl必须是字符串', 
                  'max' => 64, 'tooLong' => 'list_tpl最长64位'],
            ['detail_tpl', 'default', 'value' => ''],
            ['detail_tpl', 'string', 'message' => 'detail_tpl必须是字符串', 
                  'max' => 64, 'tooLong' => 'detail_tpl最长64位'],
            ['content_count', 'default', 'value' => 0],
            ['content_count', 'integer', 'message' => 'content_count必须为数字，或数字字符串', 
                        'min'=>0, 'tooSmall' => 'content_count最小存储0', 
                        'max'=>18446744073709551615, 'tooBig' => 'content_count最大存储18446744073709551615'],
            ['preview_count', 'default', 'value' => 0],
            ['preview_count', 'integer', 'message' => 'preview_count必须为数字，或数字字符串', 
                        'min'=>0, 'tooSmall' => 'preview_count最小存储0', 
                        'max'=>18446744073709551615, 'tooBig' => 'preview_count最大存储18446744073709551615'],
            ['sort', 'integer', 'message' => 'sort必须为数字，或数字字符串', 
                     'min'=>0, 'tooSmall' => 'sort最小存储0', 
                     'max'=>65535, 'tooBig' => 'sort最大存储65535'],
            ['display', 'default', 'value' => 1],
            ['display', 'integer', 'message' => 'display必须为数字，或数字字符串'],
            ['display', 'in', 'range' => array(1, 2), 'message' => 'display值必须在1,2中选择'],
        ];
    }

    /*添加栏目*/
    public function addCategory($data)
    {
        // P($data);
        $this->scenario = 'add';
        if(isset($data['GoodsCategory']['icon']) and is_array($data['GoodsCategory']['icon'])){
            $data['GoodsCategory']['icon'] = Tool::changeUploadFormat($data['GoodsCategory']['icon']);
        }
        if(isset($data['GoodsCategory']['preview']) and is_array($data['GoodsCategory']['preview'])){
            $data['GoodsCategory']['preview'] = Tool::changeUploadFormat($data['GoodsCategory']['preview']);
        }
        if(isset($data['GoodsCategory']['outside'])){
            $data['GoodsCategory']['outside'] = Tool::changeBool($data['GoodsCategory']['outside']);
        }
        if(isset($data['GoodsCategory']['display'])){
            $data['GoodsCategory']['display'] = Tool::changeBool($data['GoodsCategory']['display']);
        }
        if($this->load($data) and $this->validate()){
            /*取出父元素的allparentid 为了完善自己的allparentid*/
            if($this->parentid > 0){//非顶级分类的话
                $goodsCategory = GoodsCategory::find()->select('catid, parentid, allparentid, allchildid')
                        ->where('catid = :catid', [':catid' => $data['GoodsCategory']['parentid']])->one();
                if(is_null($goodsCategory)){
                    $this->addError('parentid', '上级分类不存在');
                    return false;
                }
                $this->allparentid = $goodsCategory->allparentid . ',' . $goodsCategory->catid;
            }

            $transaction = Yii::$app->db->beginTransaction();//事物处理
            $pass = true;
            try{
                /*添加栏目*/
                if($this->save(false)){
                    $catid = $this->getPrimaryKey();
                    $this->updateAll(['sort' => $catid], 'catid = :catid', [':catid' => $catid]);
                }else{
                    $pass = false;
                }

                if($pass){
                    /*循环自身的所有父元素ID，修改父元素的child 和 allchildid*/
                    for($i=0; $i<count($allParentIdArr = explode(',', $this->allparentid)); $i++){
                        if($allParentIdArr[$i]){
                            $goodsCategory = self::find()
                                        ->select('catid, parentid, allparentid, allchildid')
                                        ->where('catid = :catid', [':catid' => $allParentIdArr[$i]])
                                        ->one();
                            $goodsCategory->child = 2;
                            $goodsCategory->allchildid = ($goodsCategory->allchildid?$goodsCategory->allchildid . ',':'') . $catid;
                            if(!$goodsCategory->save(false)){
                                $pass = false;
                            }
                        }
                    }
                }

                if($pass){
                    $transaction->commit();
                    return $catid;
                }
            }catch(\Exception $exception){
                $transaction->rollback();       
                return false;
            };
        }
        return false;
    }

    /*
    修改栏目
    $data   修改的数据
    $catid     栏目ID
    */
    public function modifyCategory($data, $catid)
    {
        // P($data);
        $this->scenario = 'add';
        if(isset($data['GoodsCategory']['icon']) and is_array($data['GoodsCategory']['icon'])){
            $data['GoodsCategory']['icon'] = Tool::changeUploadFormat($data['GoodsCategory']['icon']);
        }
        if(isset($data['GoodsCategory']['preview']) and is_array($data['GoodsCategory']['preview'])){
            $data['GoodsCategory']['preview'] = Tool::changeUploadFormat($data['GoodsCategory']['preview']);
        }
        if(isset($data['GoodsCategory']['outside'])){
            $data['GoodsCategory']['outside'] = Tool::changeBool($data['GoodsCategory']['outside']);
        }
        if(isset($data['GoodsCategory']['display'])){
            $data['GoodsCategory']['display'] = Tool::changeBool($data['GoodsCategory']['display']);
        }
        $goodsCategory = GoodsCategory::find()->where('catid = :catid', [':catid' => $catid])->one();//之前的数据
        // P($data);
        // P($goodsCategory);
        $oldParentid = $goodsCategory->parentid;//保存老的parentid 为了下面比较是否更换了父级
        $oldAllparentid = $goodsCategory->allparentid;//保存老的allparentid 为了下面修改老父级的allchildid
        $oldAllchildid = $goodsCategory->allchildid;//保存老的allchildid 为了下面比较是否更换了父级
        if(!is_null($goodsCategory)){
                // P($data);
            if($this->load($data) and $this->validate()){
                if(isset($this->name)){
                    $goodsCategory->name = $this->name;
                }
                if(isset($this->icon)){
                    $goodsCategory->icon = $this->icon;
                }
                if((isset($this->parentid) and $this->parentid >= 0)){
                    $goodsCategory->parentid = $this->parentid;
                }
                if(isset($this->preview)){
                    $goodsCategory->preview = $this->preview;
                }
                if(isset($this->seo_title)){
                    $goodsCategory->seo_title = $this->seo_title;
                }
                if(isset($this->seo_keyword)){
                    $goodsCategory->seo_keyword = $this->seo_keyword;
                }
                if(isset($this->seo_describe)){
                    $goodsCategory->seo_describe = $this->seo_describe;
                }
                if(isset($this->outside)){
                    $goodsCategory->outside = $this->outside;
                }
                if(isset($this->url_target)){
                    $goodsCategory->url_target = $this->url_target;
                }
                if(isset($this->outside_url)){
                    $goodsCategory->outside_url = $this->outside_url;
                }
                if((isset($this->flag) and $this->flag >= 0)){
                    $goodsCategory->flag = $this->flag;
                }
                if(isset($this->page_tpl)){
                    $goodsCategory->page_tpl = $this->page_tpl;
                }
                if(isset($this->list_tpl)){
                    $goodsCategory->list_tpl = $this->list_tpl;
                }
                if(isset($this->detail_tpl)){
                    $goodsCategory->detail_tpl = $this->detail_tpl;
                }
                if(isset($this->display)){
                    $goodsCategory->display = $this->display;
                }
                // P($goodsCategory);


                /*
                如果分类有变化
                需要改动所有之前所有父级allparentid、child、allchildid数据
                还要改动现在的所有父级allparentid、child、allchildid数据
                */

                $transaction = Yii::$app->db->beginTransaction();//事物处理
                $pass = true;
                try{
                    if($goodsCategory->parentid != $oldParentid){
                        if($this->parentid > 0){
                            /*现在的父级数据*/
                            $parent = GoodsCategory::find()
                                        ->select('catid, parentid, allparentid, allchildid')
                                        ->where('catid = :catid', [':catid' => $data['GoodsCategory']['parentid']])
                                        ->one();

                            /*非顶级分类的话，验证父级parentid是否存在*/
                            if(is_null($parent)){
                                $this->addError('parentid', '上级分类不存在');
                                return false;
                            }

                            $goodsCategory->allparentid = $parent->allparentid . ',' . $this->parentid;//整理自身的allparentid

                            /*判断是否选择是自己和子分类*/
                            if(($this->parentid == $goodsCategory->catid) or 
                                (in_array($this->parentid, explode(',', $goodsCategory->allchildid)))){
                                $this->addError('parentid', '不能选择自身和子级');
                                return false;
                            }
                        }else{
                            $goodsCategory->allparentid = '0';//整理自身的allparentid
                        }
                                
                        if(!$goodsCategory->save(false)){//保存自身数据
                            $pass = false;
                        }

                        /*
                        修改之前所有父元素的allchildid
                        其实就是去掉自己的id 和自己子元素的id，同时看看下面还有没有子元素，如果没有的话，child字段改成1
                        */
                        if($pass){
                            for($i=0; $i<count($allParentIdArr = explode(',', $oldAllparentid)); $i++){
                                if($allParentIdArr[$i]){
                                    $tmpCategory = self::find()->select('catid, allparentid, child, allchildid')
                                               ->where('catid = :catid', [':catid' => $allParentIdArr[$i]])->one();
                                    $tmpArr = explode(',', $tmpCategory->allchildid);
                                    foreach ($tmpArr as $k => $v){
                                        if (($v == $goodsCategory->catid) or (in_array($v, explode(',', $goodsCategory->allchildid)))){
                                            unset($tmpArr[$k]);
                                        }
                                    }
                                    if(count($tmpArr)){
                                        $tmpCategory->child = 2;
                                    }else{
                                        $tmpCategory->child = 1;
                                    }
                                    $tmpCategory->allchildid = implode(',', $tmpArr);
                                    if(!$tmpCategory->save(false)){
                                        $pass = false;
                                    }
                                }
                            }
                        }

                        /*
                        修改现在所有父元素的allchildid
                        就是在所有父级 添加自身的id 和子级的id
                        */
                        if($pass and $goodsCategory->allparentid != '0'){
                            for($i=0; $i<count($allParentIdArr = explode(',', $goodsCategory->allparentid)); $i++){
                                if($allParentIdArr[$i]){
                                    $tmpCategory = self::find()
                                               ->select('catid, allparentid, child, allchildid')
                                               ->where('catid = :catid', [':catid' => $allParentIdArr[$i]])->one();
                                    $tmpCategory->child = 2;
                                    if($goodsCategory->allchildid){
                                        $tmpCategory->allchildid = ($tmpCategory->allchildid?$tmpCategory->allchildid . ',':'') . $goodsCategory->catid . ',' . $goodsCategory->allchildid;
                                    }else{
                                        $tmpCategory->allchildid = ($tmpCategory->allchildid?$tmpCategory->allchildid . ',':'') . $goodsCategory->catid;
                                    }
                                    if(!$tmpCategory->save(false)){
                                        $pass = false;
                                    }
                                }
                            }
                        }


                        /*修改自身所有子元素的allparentid*/
                        if($pass){
                            for($i=0; $i<count($allChildIdArr = explode(',', $goodsCategory->allchildid)); $i++){
                                if($allChildIdArr[$i]){
                                    $child = self::find()
                                                ->select('catid, parentid, allparentid, child, allchildid')
                                                ->where('catid = :catid', [':catid' => $allChildIdArr[$i]])->one();
                                    $parent = self::find()
                                                  ->select('catid, allparentid, child, allchildid')
                                                  ->where('catid = :catid', [':catid' => $child['parentid']])->one();
                                    $child->allparentid = $parent->allparentid . ',' . $parent->catid;
                                    $child->save(false);
                                }
                            }
                        }

                        
                    }else{
                        if(!$goodsCategory->save(false)){//保存自身数据
                            $pass = false;
                        }
                    }

                    if($pass){
                        $transaction->commit();
                        return true;
                    }
                }catch(\Exception $exception){
                    $transaction->rollback();       
                    return false;
                };
                
            }
        };
        return false;
    }

    /*删除栏目*/
    public function deleteCategory($catid)
    {
        $goodsCategory = GoodsCategory::find()->where('catid = :catid', [':catid' => $catid])->one();
        if(is_null($goodsCategory)){
            return 10013;
        };
        $transaction = Yii::$app->db->beginTransaction();//事物处理
        $pass = true;
        try{
            /*删除ID对应的数据 和 所有子级*/
            if(!$this->deleteAll('catid = :catid or FIND_IN_SET(:catid, allparentid)', [':catid' => $catid])){
                $pass = false;
            };

            if($pass){
                /*所有父级的 allchildid 去掉已经删除的id*/
                for($i=0; $i<count($allParentIdArr = explode(',', $goodsCategory->allparentid)); $i++){
                    if($allParentIdArr[$i]){
                        $tmpCategory = self::find()->select('catid, allparentid, child, allchildid')
                                   ->where('catid = :catid', [':catid' => $allParentIdArr[$i]])->one();
                        $tmpArr = explode(',', $tmpCategory->allchildid);
                        foreach ($tmpArr as $k => $v){
                            if (($v == $goodsCategory->catid) or (in_array($v, explode(',', $goodsCategory->allchildid)))){
                                unset($tmpArr[$k]);
                            }
                        }
                        if(count($tmpArr)){
                            $tmpCategory->child = 2;
                        }else{
                            $tmpCategory->child = 1;
                        }
                        $tmpCategory->allchildid = implode(',', $tmpArr);
                        if(!$tmpCategory->save(false)){
                            $pass = false;
                        }
                    }
                }
            }


            if($pass){
                $transaction->commit();
                return true;
            }
        }catch(\Exception $exception){
            $transaction->rollback();       
            return 10013;
        };
    }

    /*
    取出树形分类
    $model      带有where参数的搜索模型对象
    $flag       ele的时候，取setEleTree()方法
    */
    public static function getTreeList($model, $flag = '', $parentid = 0)
    {
        $goodsCategoryList = $model->select(['catid', 'name', 'parentid', 'allparentid', 'outside', 'url_target', 'outside_url', 'flag', 'content_count', 'preview_count', 'display'])
                    ->orderBy(['sort' => SORT_ASC])->asArray()->all();
        // P($goodsCategoryList);
        if($flag == 'ele'){
            $goodsCategoryList = self::setEleTree($goodsCategoryList, $parentid);
        }else{
            $goodsCategoryList = self::setTree($goodsCategoryList, $parentid);
        }
        return $goodsCategoryList;
    }
    /*
    递归函数
    返回一个 商品分类 树列表
    $arr        需要处理的数组
    $parentid   父ID
    */
    private static function setTree($arr, $parentid=0)
    {
        static $list = array();
        static $level = 0;//层级
        $level++;

        for($i=0; $i<count($arr); $i++){
            $arr[$i]["level"] = $level;
            $hasTotal = self::getHasNumById($arr, $arr[$i]["catid"]);//此ID下有多少条数据(不包含隐藏的栏目)
            $endTotal = self::getEndNumById($arr, $arr[$i]["catid"]);//此ID下有多少条数据(包含隐藏的栏目)
            if($arr[$i]["parentid"] == $parentid){
                if($hasTotal){//如果下面有子栏目
                    $arr[$i]["has"] = true;
                }else{
                    $arr[$i]["has"] = false;
                }
                if($endTotal){//如果下面有同级栏目
                    $arr[$i]["end"] = true;
                }else{
                    $arr[$i]["end"] = false;
                }
                array_push($list, $arr[$i]);
                self::setTree($arr, $arr[$i]["catid"]);
            }
        }
        $level--;
        return $list;
    }
    /*
    为递归函数服务
    查看父id为 $parentid 的 结果有多少个(不包含隐藏的栏目)
    $arr        匹配的数组
    $parentid   匹配的父ID
    */
    private static function getHasNumById($arr, $parentid)
    {
        $num = 0;
        foreach($arr as $k => $v){
            if(($v["parentid"] == $parentid) && $v["display"]){
                $num++;
            }
        }
        return $num;
    }
    /*
    为递归函数服务
    查看父id为 $parentid 的 结果有多少个(不包含隐藏的栏目)
    $arr        匹配的数组
    $parentid   匹配的父ID
    */
    private static function getEndNumById($arr, $parentid)
    {
        $num = 0;
        foreach($arr as $k => $v){
            if(($v["parentid"] == $parentid)){
                $num++;
            }
        }
        return $num;
    }

    //------------------element TREE(因为目录结构不一样，element TREE子栏目是children包含的)-----------------
    /*
    递归函数
    返回一个 商品分类 树列表
    $list           需要处理的原始数据
    $parentid       父ID
    */
    private static function setEleTree($list, $parentid  = 0)
    {
        $newList = array();
        $j = 0;

        for($i=0; $i<count($list); $i++){
            if($list[$i]["parentid"] == $parentid){
                // switch($list[$i]['flag']){
                //     case 1:
                //         $list[$i]['flag'] = 'hot';
                //         break;
                //     case 2:
                //         $list[$i]['flag'] = 'new';
                //         break;
                //     default:
                //         $list[$i]['flag'] = '';
                // };
                if($list[$i]["display"] == 1){
                    $list[$i]["display"] = false;
                }else{
                    $list[$i]["display"] = true;
                }
                $list[$i]['label'] = array(
                    'name' => $list[$i]['name'],
                    'flag' => $list[$i]['flag'],
                    'content_count' => $list[$i]['content_count']
                );
                unset( $list[$i]['name']);
                array_push($newList, $list[$i]);
                $newList[$j]['children'] = self::setEleTree($list, $list[$i]["catid"]);
                $j++;
            }
        }
        return $newList;
    }
    //------------------element TREE(因为目录结构不一样，element TREE子栏目是children包含的)-----------------

    
}